#include "stdafx.h"
#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTests
{		
	TEST_CLASS(LazyManCalendarTests) {
	public:
		
//@author A0080440U
		TEST_METHOD(parseTestResetFunction) {
			
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = " ";
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "reset";
			command = "reset";
			task = parse.convertUserInputToTask(stringTest,cmd);
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());
			Assert::AreEqual(time,task.getTime());
		}

		TEST_METHOD(parseTestFlexiCommandShort){
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command;
			string taskName;
			string deadline;
			string Time;
			string priority;
			time_t dateInSeconds;

			stringTest = "add CS report by fri @ 2pm! high";									// ********* must change deadline, deadline depends on what date it is today
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "add";
			taskName = "CS report";
			
			time_t rawtime;
			time(&rawtime);  /* current time in seconds */
 	        struct tm * currentTime;
 			currentTime = localtime(&rawtime);
 		    (*currentTime).tm_hour = 0;                             // making current time point to today at 00:00
			(*currentTime).tm_min = 0;
		    (*currentTime).tm_sec = 0;
	        int daysToAdd = 5 - (*currentTime).tm_wday;
			if(daysToAdd <= 0) {
				daysToAdd += 7;
			}
		
			time_t date = mktime(currentTime) + daysToAdd * 60*60*24;
			struct tm * deadlineTime;
			deadlineTime = localtime(&date);
	
			int day = (*deadlineTime).tm_mday;
			int month = (*deadlineTime).tm_mon + 1;
			
			
			deadline = to_string(day) + "/" + to_string(month);

			
			Time = "1400";
			priority = "high";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());
			Assert::AreEqual(Time,task.getTime());
			Assert::AreEqual(priority,task.getPriority());		
		}

		TEST_METHOD(parseTestDateAndStartEndTime){
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command;
			string taskName;
			string deadline;
			string time;
			string priority;
			time_t dateInSeconds;

			stringTest = "add dinner with CS group on 31/3 @ 2pm - 4pm ! low";
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "add";
			taskName = "dinner with CS group";
			deadline = "31/3";
			time = "1400-1600";
			priority = "low";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());	
			Assert::AreEqual(time,task.getTime());
			Assert::AreEqual(priority,task.getPriority());			
		}

		TEST_METHOD(parseTestDateAndStartToEndAutoTimeDinner){
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command;
			string taskName;
			string deadline;
			string time;
			string priority;
			time_t dateInSeconds;

			stringTest = "add dinner with CS group on 31/3 @ 6 - 8 ! low";
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "add";
			taskName = "dinner with CS group";
			deadline = "31/3";
			time = "1800-2000";
			priority = "low";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());	
			Assert::AreEqual(time,task.getTime());
			Assert::AreEqual(priority,task.getPriority());			
		}

		TEST_METHOD(parseTestDateAndStartToEndAutoTimeLunch){
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command;
			string taskName;
			string deadline;
			string time;
			string priority;
			time_t dateInSeconds;

			stringTest = "add lunch with CS group on 31/3 @ 12 - 2 ! low";
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "add";
			taskName = "lunch with CS group";
			deadline = "31/3";
			time = "1200-1400";
			priority = "low";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());	
			Assert::AreEqual(time,task.getTime());
			Assert::AreEqual(priority,task.getPriority());			
		}

		TEST_METHOD(parseTestDateAndStartToEndNoDot){
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command;
			string taskName;
			string deadline;
			string time;
			string priority;
			time_t dateInSeconds;

			stringTest = "add dinner with CS group on 31/3 @ 1800 - 2000! low";
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "add";
			taskName = "dinner with CS group";
			deadline = "31/3";
			time = "1800-2000";
			priority = "low";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());	
			Assert::AreEqual(time,task.getTime());
			Assert::AreEqual(priority,task.getPriority());			
		}

		TEST_METHOD(parseTestDateAndStartToEndDot){
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command;
			string taskName;
			string deadline;
			string time;
			string priority;
			time_t dateInSeconds;

			stringTest = "add dinner with CS group on 31/3 @ 18.00 - 20.00! low";
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "add";
			taskName = "dinner with CS group";
			deadline = "31/3";
			time = "1800-2000";
			priority = "low";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());	
			Assert::AreEqual(time,task.getTime());
			Assert::AreEqual(priority,task.getPriority());			
		}

		TEST_METHOD(parseTestDateAndStartToEndPMNoDot){
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command;
			string taskName;
			string deadline;
			string time;
			string priority;
			time_t dateInSeconds;

			stringTest = "add dinner with CS group on 31/3 @ 600 - 800! low";
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "add";
			taskName = "dinner with CS group";
			deadline = "31/3";
			time = "0600-2000";
			priority = "low";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());	
			Assert::AreEqual(time,task.getTime());
			Assert::AreEqual(priority,task.getPriority());			
		}

		TEST_METHOD(parseTestInvalidDateDay){
			// combining multiple inputs & equivalence partition for parsing date, 
			// either valid or invalid. this is the INVALID TEST
			string stringTest;
			Logic logic;
			stringTest = "add dinner with CS group on 32/3 @ 2pm - 4pm ! low";
			logic.start(stringTest);
			string feedback = "Invalid date";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestInvalidDateMonth){
			// combining multiple inputs & equivalence partition for parsing date, 
			// either valid or invalid. this is the INVALID TEST
			string stringTest;
			Logic logic;
			stringTest = "add dinner with CS group on 12/13 @ 2pm - 4pm ! low";
			logic.start(stringTest);
			string feedback = "Invalid date";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestInvalidDateNegativeMonth){
			// combining multiple inputs & equivalence partition for parsing date, 
			// either valid or invalid. this is the INVALID TEST
			string stringTest;
			Logic logic;
			stringTest = "add dinner with CS group on 12/-13 @ 2pm - 4pm ! low";
			logic.start(stringTest);
			string feedback = "Invalid date";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestInvalidDateLeapYearFailure){
			// combining multiple inputs & equivalence partition for parsing date, 
			// either valid or invalid. this is the INVALID TEST
			string stringTest;
			Logic logic;
			stringTest = "add dinner with CS group on 29/2 @ 2pm - 4pm ! low";
			logic.start(stringTest);
			string feedback = "Invalid date";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestInvalidTimeMinutes){
			// combining multiple inputs & equivalence partition for parsing date, 
			// either valid or invalid. this is the INVALID TEST
			string stringTest;
			Logic logic;
			string feedback;
			stringTest = "add dinner with CS group on 31/3 @ 2.64 ! low";
			logic.start(stringTest);
			feedback = "Invalid time";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestInvalidTimeHours){
			// combining multiple inputs & equivalence partition for parsing date, 
			// either valid or invalid. this is the INVALID TEST
			string stringTest;
			Logic logic;
			string feedback;
			stringTest = "add dinner with CS group on 31/3 @ 9000 ! low";
			logic.start(stringTest);
			feedback = "Invalid time";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestInvalidTimeNegative){
			// combining multiple inputs & equivalence partition for parsing date, 
			// either valid or invalid. this is the INVALID TEST
			string stringTest;
			Logic logic;
			string feedback;
			stringTest = "add dinner with CS group on 31/3 @ -3pm ! low";
			logic.start(stringTest);
			feedback = "Invalid time";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestInvalidPriority){
			// combining multiple inputs & equivalence partition for parsing date, 
			// either valid or invalid. this is the INVALID TEST
			string stringTest;
			Logic logic;
			string feedback;
			stringTest = "add dinner with CS group on 31/3 @ 2pm - 4pm ! extra high";
			logic.start(stringTest);
			feedback = "Invalid priority. Available priorities: high/medium/low";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestDayShort){
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string Time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "add ie project on sun @ 8am ! m";									// ********* must change deadline, deadline depends on what date it is today
			task = parse.convertUserInputToTask(stringTest, cmd);
			command = "add";
			taskName = "ie project";
			

			time_t rawtime;
			time(&rawtime);  /* current time in seconds */
 	        struct tm * currentTime;
 			currentTime = localtime(&rawtime);
 		    (*currentTime).tm_hour = 0;                             // making current time point to today at 00:00
			(*currentTime).tm_min = 0;
		    (*currentTime).tm_sec = 0;
	        int daysToAdd = 7 - (*currentTime).tm_wday;
			if(daysToAdd == 0) {
				daysToAdd = 7;
			}
			
			time_t date = mktime(currentTime) + daysToAdd * 60*60*24;
			struct tm * deadlineTime;
			deadlineTime = localtime(&date);
	
			int day = (*deadlineTime).tm_mday;
			int month = (*deadlineTime).tm_mon + 1;
			

			deadline = to_string(day) + "/" + to_string(month);
			Time = "0800";															
			priority = "medium";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());		
			Assert::AreEqual(Time,task.getTime());
			Assert::AreEqual(priority,task.getPriority());		
		}

		TEST_METHOD(parseTestInDays) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "add check with wj how project is coming along in 3 days";		// ********* must change deadline, deadline depends on what date it is today
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "add";
			taskName = "check with wj how project is coming along";
				time_t rawtime;
			time(&rawtime);  /* current time in seconds */
 	        struct tm * currentTime;
 			currentTime = localtime(&rawtime);
 		    (*currentTime).tm_hour = 0;                             // making current time point to today at 00:00
			(*currentTime).tm_min = 0;
		    (*currentTime).tm_sec = 0;
	        int daysToAdd = 3;
			
			time_t date = mktime(currentTime) + daysToAdd * 60*60*24;
			struct tm * deadlineTime;
			deadlineTime = localtime(&date);
	
			int day = (*deadlineTime).tm_mday;
			int month = (*deadlineTime).tm_mon + 1;
			

			deadline = to_string(day) + "/" + to_string(month);
			priority = "low";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());		
			Assert::AreEqual(priority,task.getPriority());	
		}

		TEST_METHOD(parseTestInDaysNegative){
			// combining multiple inputs & equivalence partition for parsing date, 
			// either valid or invalid. this is the INVALID TEST
			string stringTest;
			Logic logic;
			string feedback;
			stringTest = "add check with wj how project is coming along in -3 days";		
			logic.start(stringTest);
			feedback = "Invalid day";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestShortPriority){
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "add read textbook by sheldon ross by the beach by 10/3! l ";		
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "add";
			taskName = "read textbook by sheldon ross by the beach";
			deadline = "10/3";
			priority = "low";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());		
			Assert::AreEqual(priority,task.getPriority());	
		}

		TEST_METHOD(parseTestdelete){
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "delete 3";
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "delete";
			int taskLine = 3;
			taskName = EMPTY;
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskLine,task.getTaskLine());
			Assert::AreEqual(taskName,task.getTaskName());
		}

		TEST_METHOD(parseTestModifyTaskName) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "modify 4 eat poop";
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "modify";
			int taskLine = 4;
			string modifiedTaskName = "eat poop";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(modifiedTaskName,task.getModifiedTaskName());
			Assert::AreEqual(taskLine,task.getTaskLine());	
		}

		TEST_METHOD(parseTestModifyPriority) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;
			
			stringTest = "modify 2 ! low";
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "modify";
			int taskLine = 2;
			string modifiedPriority = "low";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(modifiedPriority,task.getModifiedPriority());
			Assert::AreEqual(taskLine,task.getTaskLine());	
		}

		TEST_METHOD(parseTestModifyDeadline) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "modify 8  by fri";											// ********* must change deadline, deadline depends on what date it is today
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "modify";
			int taskLine = 8;
			
			time_t rawtime;
			time(&rawtime);  /* current time in seconds */
 	        struct tm * currentTime;
 			currentTime = localtime(&rawtime);
 		    (*currentTime).tm_hour = 0;                             // making current time point to today at 00:00
			(*currentTime).tm_min = 0;
		    (*currentTime).tm_sec = 0;
	        int daysToAdd = 5 - (*currentTime).tm_wday;
			if(daysToAdd <= 0) {
				daysToAdd += 7;
			}
			
			time_t date = mktime(currentTime) + daysToAdd * 60*60*24;
			struct tm * deadlineTime;
			deadlineTime = localtime(&date);
	
			int day = (*deadlineTime).tm_mday;
			int month = (*deadlineTime).tm_mon + 1;
			

			string modifiedDeadline = to_string(day) + "/" + to_string(month);
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(modifiedDeadline,task.getModifiedDeadline());
			Assert::AreEqual(taskLine,task.getTaskLine());	
		}

		TEST_METHOD(parseTestModifyDate) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "modify 8  by 25/12";										
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "modify";
			int taskLine = 8;
			string modifiedDeadline = "25/12";
			int modifiedDateInSeconds = 1419436800;
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(modifiedDeadline,task.getModifiedDeadline());
			Assert::AreEqual(taskLine,task.getTaskLine());	
			Assert::AreEqual(modifiedDateInSeconds, int(task.getModifiedDateInSeconds()));
		}
		
		TEST_METHOD(parseTestModifyDateWithYear) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "modify 8  by 31/3/2014";										
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "modify";
			int taskLine = 8;
			string modifiedDeadline = "31/3";
			int modifiedDateInSeconds = 1396195200;
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(modifiedDeadline,task.getModifiedDeadline());
			Assert::AreEqual(taskLine,task.getTaskLine());	
			Assert::AreEqual(modifiedDateInSeconds, int(task.getModifiedDateInSeconds()));
		}

		TEST_METHOD(parseTestModfiyTime) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "modify 8 @ 2";										
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "modify";
			int taskLine = 8;
			string modifiedTime = "1400";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(modifiedTime,task.getModifiedTime());
			Assert::AreEqual(taskLine,task.getTaskLine());	
		}

		TEST_METHOD(parseTestModfiyNegativeTime) {
			string stringTest;
			Logic logic;
			string feedback;
			stringTest =  "modify 8 @ -1";										
			logic.start(stringTest);
			feedback = "Invalid time";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestModifyNegativeLine) {
			string stringTest;
			Logic logic;
			string feedback;
			stringTest =  "modify -1 by 25/12";										
			logic.start(stringTest);
			feedback = "Invalid modification";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestModifyNegativeDate) {
			string stringTest;
			Logic logic;
			string feedback;
			stringTest =  "modify 1 by -25/12";										
			logic.start(stringTest);
			feedback = "Invalid modification";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestModifyWrongDay) {
			string stringTest;
			Logic logic;
			string feedback;
			stringTest =  "modify 1  by TGIF";										
			logic.start(stringTest);
			feedback = "Invalid modification";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestModifyWrongPriority) {
			string stringTest;
			Logic logic;
			string feedback;
			stringTest =  "modify 1 !taeyeon";										
			logic.start(stringTest);
			feedback = "Invalid priority to be modified to. Available priorities: high/medium/low";
			Assert::AreEqual(feedback,logic.getForUIFeedback());
		}

		TEST_METHOD(parseTestDate) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;
			
			stringTest = "add 8 by 25/12";										
			task = parse.convertUserInputToTask(stringTest,cmd);
			deadline = "25/12";
			dateInSeconds = 1419436800;
			Assert::AreEqual(deadline,task.getDeadline());
			Assert::AreEqual(int(dateInSeconds), int(task.getDateInSeconds()));
		}

		TEST_METHOD(parseTestSearchByDeadlineDay) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "search by fri";											
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "search";
			taskName = "by fri";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());	
		}

		TEST_METHOD(parseTestSearchDate) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "search 13/4";											
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "search";
			taskName = "13/4";
			deadline = "";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());	
			Assert::AreEqual(deadline,task.getDeadline());
		}

		TEST_METHOD(parseTestSearchTaskName) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;

			stringTest = "search c";											
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "search";
			taskName = "c";
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());	
		}

		TEST_METHOD(parseTestAddingEmptyString) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;
			stringTest = "add ";											
			task = parse.convertUserInputToTask(stringTest,cmd);
			command = "add";
			taskName = EMPTY;
			Assert::AreEqual(command,cmd);
			Assert::AreEqual(taskName,task.getTaskName());
		}

		TEST_METHOD(parseTestAddwithAllDetails) {
			Parser parse;
			Task task;
			string cmd;
			string stringTest;
			string command = EMPTY;
			string taskName = EMPTY;
			string deadline = EMPTY;
			string time = EMPTY;
			string priority = EMPTY;
			time_t dateInSeconds = NIL;
			
			stringTest = "v0.2 demo to Prof Damith by 27/3 @ 1200 ! high * done & 1395849600";
			task = parse.convertToTask(stringTest);
			taskName = "v0.2 demo to Prof Damith";
			deadline = "27/3";
			time = "1200";
			priority = "high";
			string  status = "done";
			int seconds = 1395849600;
			int actualDateInSeconds = int(task.getDateInSeconds());

			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(deadline,task.getDeadline());
			Assert::AreEqual(time,task.getTime());
			Assert::AreEqual(priority,task.getPriority());
			Assert::AreEqual(status,task.getStatus());
			Assert::AreEqual(seconds,actualDateInSeconds);
		}
		
		TEST_METHOD(addTestNoTaskName) {
			Parser parse;
			Task task;
			string cmd;
			vector<Task> store;
			Add add;
			char errorFeedback[] = "add error, no taskname";
			string feedback;
			string expectedFeedback;

			try {
				add.execute(task,store);
			}
			catch (exception & e) {
				Assert::AreEqual(errorFeedback,e.what());
			}
		}

		TEST_METHOD(addTest) {
			Parser parse;
			Task task;
			string cmd;
			vector<Task> store;
			Add add;
			string feedback;
			string expectedFeedback;


			task = parse.convertUserInputToTask("add lunch with van on 6/6 @ 12-2pm ! low",cmd);
			feedback = add.execute(task,store);
			expectedFeedback = "added 'lunch with van'";
			Assert::AreEqual(expectedFeedback,feedback);
			string taskName = "lunch with van";
			string deadline = "6/6";
			string time = "1200-1400";
			string priority = LOW;
			Assert::AreEqual(taskName,store[0].getTaskName());
			Assert::AreEqual(deadline,store[0].getDeadline());
			Assert::AreEqual(time,store[0].getTime());
			Assert::AreEqual(priority,store[0].getPriority());
		}

		TEST_METHOD(addTestDefault) {
			Parser parse;
			Task task;
			string cmd;
			vector<Task> store;
			Add add;
			string feedback;
			string expectedFeedback;

			// testing default time date priority
			task = parse.convertUserInputToTask("add check with wj ie2150 project status",cmd);
			feedback = add.execute(task,store);
			expectedFeedback = "added 'check with wj ie2150 project status'";
			Assert::AreEqual(expectedFeedback,feedback);
			string taskName = "check with wj ie2150 project status";
			string deadline = EMPTY;
			string time = " ";
			string priority = LOW;
			Assert::AreEqual(taskName,store[0].getTaskName());
			Assert::AreEqual(deadline,store[0].getDeadline());
			Assert::AreEqual(time,store[0].getTime());
			Assert::AreEqual(priority,store[0].getPriority());		
		}
		
//@author A0100088R
		TEST_METHOD(deleteTest) {
			Delete del;
			Parser parse;
			string feedback;
			string expectedFeedback;
			vector<Task> store;
			vector<Task> dummy; // to simulate forUIDisplay
			string cmd;

			for(int i = 1 ; i < 11; i++) {
				Task task;
				task.changeTaskName(to_string(i));
				store.push_back(task);
			}


			//testing inside boundary
			Task task = parse.convertUserInputToTask("delete 5",cmd);
			feedback = del.execute(task,store,dummy);

			vector<string> expected;
			
			for(int i = 1; i < 11; i++) {
				if(i != 5) {
				expected.push_back(to_string(i));
				}
			}

			for(unsigned int i = 0 ; i < expected.size(); i++) {
				Assert::AreEqual(expected[i],(store[i]).getTaskName());
			}

			// test outside of bounds
			char errorFeedback[] = "Invalid line number";
			try {
				task = parse.convertUserInputToTask("delete 12", cmd);
				feedback = del.execute(task,store,dummy); 
			}
			catch (exception & e) { 
				Assert::AreEqual(errorFeedback,e.what());
				for(unsigned int i = 0 ; i < expected.size(); i++) {
					Assert::AreEqual(expected[i],(store[i]).getTaskName());
				}
		
			}
		} 
		
		TEST_METHOD(filterTestStatus) {
			Filter filter;
			vector<Task> store;
			vector<Task> output;
			Parser parse;
			Task task;
			string cmd;

			task = parse.convertUserInputToTask("add hello world by tmr ! low",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add project meeting by tmr !m",cmd);
			task.changeStatus(DONE);
			store.push_back(task);
			task = parse.convertUserInputToTask("add dinner in 2 days  ! h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add CS meeting in 3 days @2pm !h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add cs demo in 3 days @3pm !h",cmd);
			task.changeStatus(DONE);
			store.push_back(task);
			task = parse.convertUserInputToTask("add lunch by tmr ! low",cmd);
			store.push_back(task);
			
			Assert::AreEqual(size_t(6),store.size());
			output = filter.execute(DONE,store);			
			
			Assert::AreEqual(size_t(4),output.size());
			for(vector<Task>::iterator iter = output.begin(); iter != output.end(); iter++){
				Assert::AreNotEqual(DONE, (*iter).getStatus());
			}
		}

		TEST_METHOD(filterTestPriority) {
			Filter filter;
			vector<Task> store;
			Parser parse;
			Task task;
			string cmd;
			vector<Task> output;

			task = parse.convertUserInputToTask("add hello world by tmr ! low",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add project meeting by tmr !m",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add dinner in 2 days  ! h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add CS meeting in 3 days @2pm !h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add cs demo in 3 days @3pm !h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add lunch by tmr ! low",cmd);
			store.push_back(task);

			output = filter.execute(HIGH,store);

			for(vector<Task>::iterator iter = output.begin(); iter != output.end(); iter++){
				Assert::AreNotEqual(HIGH, (*iter).getPriority());
			}
		}

		TEST_METHOD(sortTestPriority) {
			Sorter sort;
			vector <Task> store;
			Parser parse;
			Task task;
			string cmd;

			task = parse.convertUserInputToTask("add hello world by tmr ! low",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add dinner in 2 days time ! h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add project meeting in 3 days @2pm !h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add cs demo in 3 days time @3pm !h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add lunch by tmr ! low",cmd);
			store.push_back(task);

			store = sort.start(PRIORITY,store);

			Assert::AreEqual(size_t(5),store.size());
			string taskName = "dinner";
			Assert::AreEqual(taskName,store[0].getTaskName());
			taskName = "project meeting";
			Assert::AreEqual(taskName,store[1].getTaskName());
			taskName = "cs demo";
			Assert::AreEqual(taskName,store[2].getTaskName());
			taskName = "hello world";
			Assert::AreEqual(taskName,store[3].getTaskName());
			taskName = "lunch";
			Assert::AreEqual(taskName,store[4].getTaskName());
		}

		TEST_METHOD(sortTestTime) {
			Sorter sort;
			vector <Task> store;
			Parser parse;
			Task task;
			string cmd;

			task = parse.convertUserInputToTask("add hello world by tmr @ 4pm! low",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add dinner in 2 days @ 2pm !h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add project meeting in 3 days @ 2pm !m",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add lunch with van in 3 days @ 2pm !l",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add buffet in 3 days @ 2pm !l",cmd);
			store.push_back(task);

			store = sort.start(TIME,store);

			Assert::AreEqual(size_t(5),store.size());
			string taskName = "dinner";
			Assert::AreEqual(taskName,store[0].getTaskName());
			taskName = "project meeting";
			Assert::AreEqual(taskName,store[1].getTaskName());
			taskName = "buffet";
			Assert::AreEqual(taskName,store[2].getTaskName());
			taskName = "lunch with van";
			Assert::AreEqual(taskName,store[3].getTaskName());
			taskName = "hello world";
			Assert::AreEqual(taskName,store[4].getTaskName());
		}

		TEST_METHOD(sortTestTask) {
			Sorter sort;
			vector <Task> store;
			Parser parse;
			Task task;
			string cmd;

			task = parse.convertUserInputToTask("add hello world by tmr @ 4pm! low",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add dinner1 in 2 days @ 2pm! l",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add dinner2 in 3 days @3pm !l",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add dinner3 in 3 days @5pm !l",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add dinner4 in 3 days @5pm !h",cmd);
			store.push_back(task);


			store = sort.start(TASK,store);

			Assert::AreEqual(size_t(5),store.size());
			string taskName = "dinner1";
			Assert::AreEqual(taskName,store[0].getTaskName());
			taskName = "dinner2";
			Assert::AreEqual(taskName,store[1].getTaskName());
			taskName = "dinner3";
			Assert::AreEqual(taskName,store[2].getTaskName());
			taskName = "dinner4";
			Assert::AreEqual(taskName,store[3].getTaskName());
			taskName = "hello world";
			Assert::AreEqual(taskName,store[4].getTaskName());



		}

//@author A0102103L
		TEST_METHOD(modifyTest) {
			vector<Task> store;
			vector<Task> dummy; // to simulate forUIDisplay 
			Modify modify;
			Parser parse;
			Task task;
			string cmd;

			task = parse.convertUserInputToTask("add 1 banana",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 2 cows eat shit",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 3 flying frogs",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 4 pretty girls",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 5 poor men",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 6",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 7 days a week",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 8 + 10 = 18/18 for ce2 by 7/11",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 9 dead elephants on 31/12",cmd);
			store.push_back(task);
			
			// testing modify date
			task = parse.convertUserInputToTask("modify 9 by 24/12",cmd);
			string feedback = modify.execute(task,store,dummy);
			string expectedFeedback = "modified from '31/12' to '24/12'";
			Assert::AreEqual(expectedFeedback,feedback);
			string deadline = "24/12";
			Assert::AreEqual(deadline,store[8].getDeadline());
			
			string taskName = "9 dead elephants";
			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(LOW,task.getPriority());
			Assert::AreEqual(deadline,task.getModifiedDeadline());
			deadline = "31/12";
			Assert::AreEqual(deadline,task.getDeadline());


			//testing modify priority
			task = parse.convertUserInputToTask("modify 1 ! h",cmd);
			feedback = modify.execute(task,store,dummy);
			expectedFeedback = "modified from 'low' to 'high'";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(HIGH,store[0].getPriority());
			
			//testing modify taskname
			task = parse.convertUserInputToTask("modify 7 one week",cmd);
			feedback = modify.execute(task,store,dummy);
			expectedFeedback = "modified from '7 days a week' to 'one week'";
			Assert::AreEqual(expectedFeedback,feedback);
			taskName = "one week";
			Assert::AreEqual(taskName,store[6].getTaskName());
		
			task = parse.convertUserInputToTask("modify 9 by 25/12",cmd);
			feedback = modify.execute(task,store,dummy);
			expectedFeedback = "modified from '24/12' to '25/12'";
			Assert::AreEqual(expectedFeedback,feedback);
			deadline = "25/12";
			int modifiedDateInSeconds = 1419436800;
			Assert::AreEqual(deadline,store[8].getDeadline());
			Assert::AreEqual(modifiedDateInSeconds,int(store[8].getDateInSeconds()));

			task = parse.convertUserInputToTask("modify 9 by 24/12",cmd);
			feedback = modify.execute(task,store,dummy);
			expectedFeedback = "modified from '25/12' to '24/12'";
			Assert::AreEqual(expectedFeedback,feedback);
			deadline = "24/12";
			modifiedDateInSeconds = 1419350400;
			Assert::AreEqual(deadline,store[8].getDeadline());
			Assert::AreEqual(modifiedDateInSeconds,int(store[8].getDateInSeconds()));
		}

		TEST_METHOD(undoTest) {
			Logic test;
			Undo undo;
			History history;
			Modify modify;
			vector<Task> store;
			vector<Task> forUI;
			Event testEvent;
			Task task;

			task.changeTaskName("hello world");
			store.push_back(task);
			forUI.push_back(task);

			task.changeTaskName(EMPTY);
			task.changeTaskLine(1);
			task.changeModifiedTaskName("HELLO WORLD");
			modify.execute(task,store,forUI);
			testEvent.changeCommand(MODIFY);
			testEvent.changeTask(task);
			history.addToRecords(testEvent);

			string taskName = "hello world";
			string modifiedTaskName = "HELLO WORLD";
			string priority = LOW;
			string time = EMPTY;
			string deadline = EMPTY;
			string status = WIP;
			string modifiedStatus = EMPTY;

			Assert::AreEqual(taskName,task.getTaskName());
			Assert::AreEqual(modifiedTaskName,task.getModifiedTaskName());
			Assert::AreEqual(priority,task.getPriority());
			Assert::AreEqual(priority,task.getModifiedPriority());
			Assert::AreEqual(deadline,task.getDeadline());
			Assert::AreEqual(deadline,task.getModifiedDeadline());
			Assert::AreEqual(time,task.getTime());
			Assert::AreEqual(time,task.getModifiedTime());
			Assert::AreEqual(status,task.getStatus());
			Assert::AreEqual(modifiedStatus,task.getModifiedStatus());
		}

		TEST_METHOD(displayTest) {
			Logic logic;

			logic.start("reset");
			logic.start("add ask mr tan about 2150");
			logic.start("add lunch meeting with cs group on 15/5 @12-2pm! high");
			logic.start("add lunch with van on 6/6 @ 12-2pm ! l");
			logic.start("add dinner with sx on 25/12 ! medium");
			
			string taskName1 = "ask mr tan about 2150";
			string taskName2 = "lunch meeting with cs group";
			string taskName3 = "lunch with van";
			string taskName4 = "dinner with sx";

			//check for display and correct output size
			logic.start("display");
			vector <Task> output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(4),output.size());
			Assert::AreEqual(taskName1,output[0].getTaskName());
			Assert::AreEqual(taskName2,output[1].getTaskName());
			Assert::AreEqual(taskName3,output[2].getTaskName());
			Assert::AreEqual(taskName4,output[3].getTaskName());

			//check for display low and correct output size
			logic.start("display low");
			output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(2),output.size());
			Assert::AreEqual(taskName1,output[0].getTaskName());
			Assert::AreEqual(taskName3,output[1].getTaskName());

			//check for display medium and correct output size
			logic.start("display medium");
			output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(1),output.size());
			Assert::AreEqual(taskName4,output[0].getTaskName());

			//check for display high and correct output size
			logic.start("display high");
			output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(1),output.size());
			Assert::AreEqual(taskName2,output[0].getTaskName());

			//check for display done and correct output size
			logic.start("display");
			logic.start("mark 1 done");
			logic.start("display done");
			output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(1),output.size());
			Assert::AreEqual(taskName1,output[0].getTaskName());

			//check for display cmi and correct output size
			logic.start("display");
			logic.start("mark 2 cmi");
			logic.start("display cmi");
			output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(1),output.size());
			Assert::AreEqual(taskName2,output[0].getTaskName());

			//check for display archive and correct output size
			logic.start("display");
			logic.start("mark 3 archive");
			logic.start("display archive");
			output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(1),output.size());
			Assert::AreEqual(taskName3,output[0].getTaskName());

			//check for display wip and correct output size
			logic.start("display wip");
			output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(1),output.size());
			Assert::AreEqual(taskName4,output[0].getTaskName());

			//check for display all and correct output size
			logic.start("display all");
			output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(4),output.size());
			Assert::AreEqual(taskName1,output[0].getTaskName());
			Assert::AreEqual(taskName2,output[1].getTaskName());
			Assert::AreEqual(taskName3,output[2].getTaskName());
			Assert::AreEqual(taskName4,output[3].getTaskName());

			//check for display (without archive) and correct output size
			logic.start("display");
			output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(3),output.size());
			Assert::AreEqual(taskName1,output[0].getTaskName());
			Assert::AreEqual(taskName2,output[1].getTaskName());
			Assert::AreEqual(taskName4,output[2].getTaskName());
		}

//@author A0096466N
		TEST_METHOD(markTestValid) {
			Logic logic;

			logic.start("reset");
			logic.start("add lunch meeting with cs group on 15/5 @12-2pm! high");
			logic.start("add lunch with van on 6/6 @ 12-2pm ! l");
			logic.start("add dinner with sx on 25/12");
			logic.start("add ask mr tan about 2150");
			logic.start("display");

			vector <Task> output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(4),output.size());
			
			logic.start("mark 1 done");
			logic.start("mark 2 cmi");
			logic.start("mark 3 archive");
			logic.start("display all");
			output = logic.getForUIDisplay();

			Assert::AreEqual(DONE,output[0].getStatus());
			Assert::AreEqual(CMI,output[1].getStatus());
			Assert::AreEqual(ARCHIVE,output[2].getStatus());
			Assert::AreEqual(WIP,output[3].getStatus());
		}

		TEST_METHOD(markTestInvalid) {
			Logic logic;
			logic.start("reset");
			logic.start("add lunch meeting with cs group on 15/5 @12-2pm! high");
			logic.start("add lunch with van on 6/6 @ 12-2pm ! l");
			logic.start("add dinner with sx on 25/12");
			logic.start("add ask mr tan about 2150");
			logic.start("display");

			vector <Task> output = logic.getForUIDisplay();
			Assert::AreEqual(size_t(4),output.size());

			//marking to same status
			logic.start("mark 1 wip");
			output = logic.getForUIDisplay();
			string feedback = logic.getForUIFeedback();
			string expectedFeedback = "Task already has that status";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(WIP,output[0].getStatus());

			//marking invalid line number
			logic.start("mark 0 wip");
			output = logic.getForUIDisplay();
			feedback = logic.getForUIFeedback();
			expectedFeedback = "Invalid line number";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(WIP,output[0].getStatus());

			//marking invalid line number
			logic.start("mark 5 wip");
			output = logic.getForUIDisplay();
			feedback = logic.getForUIFeedback();
			expectedFeedback = "Invalid line number";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(WIP,output[0].getStatus());

			//marking to invalid status
			logic.start("mark 3 doen");
			output = logic.getForUIDisplay();
			feedback = logic.getForUIFeedback();
			expectedFeedback = "Invalid status type. Available statuses: wip/done/cmi/archive";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(WIP,output[2].getStatus());

			//marking to nothing
			logic.start("mark 2");
			output = logic.getForUIDisplay();
			feedback = logic.getForUIFeedback();
			expectedFeedback = "Nothing to mark to";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(WIP,output[1].getStatus());
		}

		TEST_METHOD(searchTestHaveMatches) {
			
			vector<Task> store;
			vector<Task> output;
			string cmd;
			Task task;
			Parser parse;
			Searcher search;

			task = parse.convertUserInputToTask("add 1 banana",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 2 cows eat shit",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 3 flying frogs",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 4 pretty girls",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 5 poor men",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 6",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 7 days a week",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 8 + 10 = 18/18 for ce2 by 7/11",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 9 dead elephants on 31/12",cmd);
			store.push_back(task);
					
			output = search.execute("flying",store);
			string taskName = "3 flying frogs";
			Assert::AreEqual(taskName,output[0].getTaskName());
			Assert::AreEqual(size_t(1),output.size());

			// search date interval
			output = search.execute("31/3- 31/12",store);
			string taskName1 = "8 + 10 = 18/18 for ce2";
			string taskName2 = "9 dead elephants";
			Assert::AreEqual(size_t(2),output.size());
			Assert::AreEqual(taskName1, output[0].getTaskName());
			Assert::AreEqual(taskName2, output[1].getTaskName());
			
			// typo search
			output = search.execute("elephanst",store); 
			taskName = "9 dead elephants";
			Assert::AreEqual(taskName,output[0].getTaskName());
			Assert::AreEqual(size_t(1), output.size());

			// search invalid date, however, since it is invalid date, it is assumed that
			// the date is a taskname
			output = search.execute("72/3",store);
			Assert::AreEqual(size_t(0),output.size());
			
		}

		TEST_METHOD(searchTestNoMatches) {
			
			vector<Task> store;
			vector<Task> output;
			string cmd;
			Task task;
			Parser parse;
			Searcher search;

			task = parse.convertUserInputToTask("add 1 banana",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 2 cows eat shit",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 3 flying frogs",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 4 pretty girls",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 5 poor men",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 6",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 7 days a week",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 8 + 10 = 18/18 for ce2 by 7/11",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 9 dead elephants on 31/12",cmd);
			store.push_back(task);
					
			output = search.execute("flying tree",store);
			Assert::AreEqual(size_t(0),output.size());
			
			
			// search date interval
			output = search.execute("31/6- 31/7",store);
			Assert::AreEqual(size_t(0),output.size());
			
			
		}

		TEST_METHOD(searchTestEmptyStore) {
			
			vector<Task> store;
			vector<Task> output;
			string cmd;
			Task task;
			Parser parse;
			Searcher search;
		
			try {
			output = search.execute("flying tree",store);
			}
			catch (exception & e) {
				char feedback[] = "No tasks to search from";
				Assert::AreEqual(feedback,e.what());	
			}
			
	
			
		}

		TEST_METHOD(reminderTestNonEmptyStore) {
			
			vector<Task> store;
			vector<Task> output;
			string cmd;
			Task task;
			Parser parse;
			Searcher search;
			Reminder reminder;

			
			task = parse.convertUserInputToTask("add 1 banana by tmr",cmd);				
			store.push_back(task);
			task = parse.convertUserInputToTask("add 2 cows eat shit by the day after tmr ! medium",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 3 flying frogs in 3 days ! h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 4 pretty girls in 10 days",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 5 poor men in 5 days ! h",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 6 in 20 days",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 7 days a week in 12 days",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 8 + 10 = 18/18 for ce2 by 7/11",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add 9 dead elephants on 31/12",cmd);
			store.push_back(task);
					
			output = reminder.execute(store);
			Assert::AreEqual(size_t(3),output.size());
			string taskName = "1 banana";
			Assert::AreEqual(taskName,output[0].getTaskName());
			taskName = "2 cows eat shit";
			Assert::AreEqual(taskName,output[1].getTaskName());
			taskName = "3 flying frogs";
			Assert::AreEqual(taskName,output[2].getTaskName());


		}
	
		TEST_METHOD(reminderTestEmptyStore) {
			
			vector<Task> store;
			vector<Task> output;
			string cmd;
			Task task;
			Parser parse;
			Searcher search;
			Reminder reminder;

			output = reminder.execute(store);
			Assert::AreEqual(size_t(0),output.size());
		}

		TEST_METHOD(resetTest) {
			Logic test;
			vector<Task> output;
			string data;

			test.start("reset");


			//ensuring vector is empty;
			Assert::AreEqual(size_t(NIL),output.size());
			
			// ensuring txt storage is empty
			ifstream readFile(FILENAME_SCHEDULE);
			int i = 0;
			while(readFile >> data) {
				i++;
			}
			readFile.close();
			Assert::AreEqual(0,i);

			
			// adding 3 things into program
			test.start("add CS project");
			test.start("add hello world");
			test.start("add bla bla bla");

			
			// ensuring that 3 things have been added to vector
			test.start("display");		// must call display cause when adding, only the added task is displayed.
			output = test.getForUIDisplay();			
			Assert::AreEqual(size_t(3),output.size());

			// ensuring that 3 things have been added to txt storage
			readFile.open(FILENAME_SCHEDULE);
			i = 0;
			while(getline(readFile,data)) {
				i++;
			}
			Assert::AreEqual(3,i);

			
			// attempting to reset
			test.start("reset");

			
			// vector should now be empty again
			output = test.getForUIDisplay();			
			Assert::AreEqual(size_t(0),output.size());

			// txt storage should now be empty again
			readFile.open(FILENAME_SCHEDULE);
			i = 0;
			while(readFile >> data) {
				i++;
			}
			Assert::AreEqual(0,i);

			readFile.close();
		}

		TEST_METHOD(autoEditStatusTest) {
				
			AutoEditStatus autoEditStatus;
			Task task;
			Parser parse;
			string cmd;
			vector<Task> store;

			task = parse.convertUserInputToTask("add this task should be archived on 20/3/14",cmd);
			task.changeStatus(DONE);
			store.push_back(task);

			task = parse.convertUserInputToTask("add this task should be marked as CMI as overdue on 31/3/14",cmd);
			store.push_back(task);
		
			task = parse.convertUserInputToTask("add this task should not be modified by tmr",cmd);
			store.push_back(task);
			
			autoEditStatus.execute(store);

			Assert::AreEqual(ARCHIVE,store[0].getStatus());
			Assert::AreEqual(CMI,store[1].getStatus());
			Assert::AreEqual(WIP,store[2].getStatus());
		}

		TEST_METHOD(clashTestEmptyStore) {
			vector<Task>store;
			Clash clash;
			string warning;
			try {
				warning = clash.execute(store);
			}
			catch (exception & e){
				Assert::AreEqual("Nothing to display", e.what());
			}
		}

		TEST_METHOD(clashTestHaveClash) {
			vector<Task> store;
			Clash clash;
			Task task;
			Parser parse;
			string cmd;
			string warning;

			task = parse.convertUserInputToTask("add CS lecture on friday @ 4-6pm",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add dinner date on friday @ 5.30pm-7pm",cmd);
			store.push_back(task);

			warning = clash.execute(store);
			string expectedWarning = "Timing clash involving no 1 & 2";
			Assert::AreEqual(expectedWarning,warning);
		}

		TEST_METHOD(clashTestNoClash) {
			vector<Task> store;
			Clash clash;
			Task task;
			Parser parse;
			string cmd;
			string warning;

			task = parse.convertUserInputToTask("add CS lecture on friday @ 4-6pm",cmd);
			store.push_back(task);
			task = parse.convertUserInputToTask("add dinner date on friday @ 6pm-7pm",cmd);
			store.push_back(task);

			warning = clash.execute(store);
			string expectedWarning = EMPTY;
			Assert::AreEqual(expectedWarning,warning);
		}

		TEST_METHOD(storageTest) {
			Storage storage;
			vector<string> strings;
			string str;

			storage.rewrite(strings);
			storage.getStorage(strings);
			Assert::AreEqual(size_t(NIL),strings.size());
			
			str = "HELLO WORLD";
			storage.addTask(str);
			storage.getStorage(strings);
			Assert::AreEqual(size_t(1),strings.size());
			Assert::AreEqual(str,strings[0]);

			strings.clear();
			storage.rewrite(strings);
			storage.getStorage(strings);
			Assert::AreEqual(size_t(NIL),strings.size());
			
		}

		
		// reset -> display -> add -> modify -> add -> display -> clash -> mark -> delete -> reset -> undo
		TEST_METHOD(integratedTest1) {
			Logic logic;
			string feedback;
			string expectedFeedback;
			string warning;
			string expectedWarning;
			string expectedTaskName;
			string expectedPriority;
			string expectedDeadline;
			string expectedTime;
			vector<Task> output;

			//reset
			logic.start("reset");
			
			//
			logic.start("display");
			output = logic.getForUIDisplay();
			feedback = logic.getForUIFeedback();
			
			expectedFeedback = "Nothing to Display";
			Assert::AreEqual(size_t(NIL),output.size());
			Assert::AreEqual(expectedFeedback,feedback);

			//add
			logic.start("add lunch meeting with cs group on 15/5 @12-2pm! high");
			feedback = logic.getForUIFeedback();
			output = logic.getForUIDisplay();

			expectedFeedback = "added 'lunch meeting with cs group'";
			expectedTaskName = "lunch meeting with cs group";
			expectedPriority = HIGH;
			expectedDeadline = "15/5";
			expectedTime = "1200-1400";

			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(expectedTaskName,output[0].getTaskName());
			Assert::AreEqual(expectedPriority,output[0].getPriority());
			Assert::AreEqual(expectedDeadline,output[0].getDeadline());
			Assert::AreEqual(expectedTime,output[0].getTime());

			//modify
			logic.start("modify 1 ! medium");
			feedback = logic.getForUIFeedback();
			output = logic.getForUIDisplay();

			expectedFeedback = "modified from 'high' to 'medium'";
			expectedPriority = MEDIUM;

			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(expectedTaskName,output[0].getTaskName());
			Assert::AreEqual(expectedPriority,output[0].getPriority());
			Assert::AreEqual(expectedDeadline,output[0].getDeadline());
			Assert::AreEqual(expectedTime,output[0].getTime());


			//modify date error
			logic.start("modify 1 by 15/13");
			feedback = logic.getForUIFeedback();
			output = logic.getForUIDisplay();

			expectedFeedback = "Invalid date";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(expectedTaskName,output[0].getTaskName());
			Assert::AreEqual(expectedPriority,output[0].getPriority());
			Assert::AreEqual(expectedDeadline,output[0].getDeadline());
			Assert::AreEqual(expectedTime,output[0].getTime());

			//modify priority error
			logic.start("modify 1 ! super high");
			feedback = logic.getForUIFeedback();
			output = logic.getForUIDisplay();

			expectedFeedback = "Invalid priority to be modified to. Available priorities: high/medium/low";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(expectedTaskName,output[0].getTaskName());
			Assert::AreEqual(expectedPriority,output[0].getPriority());
			Assert::AreEqual(expectedDeadline,output[0].getDeadline());
			Assert::AreEqual(expectedTime,output[0].getTime());

			//modify time error
			logic.start("modify 1 @1365");
			feedback = logic.getForUIFeedback();
			output = logic.getForUIDisplay();

			expectedFeedback = "Invalid time";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(expectedTaskName,output[0].getTaskName());
			Assert::AreEqual(expectedPriority,output[0].getPriority());
			Assert::AreEqual(expectedDeadline,output[0].getDeadline());
			Assert::AreEqual(expectedTime,output[0].getTime());


			//add 
			logic.start("add shopping with sis on 15/5 @1pm-5pm");
			feedback = logic.getForUIFeedback();
			output = logic.getForUIDisplay();

			expectedFeedback = "added 'shopping with sis'";
			expectedTaskName = "shopping with sis";
			expectedPriority = LOW;
			expectedDeadline = "15/5";
			expectedTime = "1300-1700";

			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(expectedTaskName,output[0].getTaskName());
			Assert::AreEqual(expectedPriority,output[0].getPriority());
			Assert::AreEqual(expectedDeadline,output[0].getDeadline());
			Assert::AreEqual(expectedTime,output[0].getTime());


			//display
			logic.start("display");
			output = logic.getForUIDisplay();
			feedback = logic.getForUIFeedback();
			
			expectedFeedback = "Displaying ";
			expectedTaskName = "lunch meeting with cs group";
			Assert::AreEqual(expectedTaskName,output[0].getTaskName());
			expectedTaskName = "shopping with sis";
			Assert::AreEqual(expectedTaskName, output[1].getTaskName());
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(size_t(2),output.size());


			//clash
			warning = logic.getForUIWarning();
			expectedWarning = "Timing clash involving no 1 & 2";
			Assert::AreEqual(expectedWarning,warning);
			
			
			//mark 
			logic.start("mark 2 cmi");
			feedback = logic.getForUIFeedback();
			output = logic.getForUIDisplay();

			expectedFeedback = "marked 'shopping with sis' as 'cmi'";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(CMI,output[1].getStatus());


			//delete
			logic.start("delete 2");
			feedback = logic.getForUIFeedback();
			output = logic.getForUIDisplay();
			warning = logic.getForUIWarning();

			expectedFeedback = "deleted 'shopping with sis'";
			expectedWarning = EMPTY;
			expectedTaskName = "lunch meeting with cs group";
			Assert::AreEqual(expectedTaskName,output[0].getTaskName());
			Assert::AreEqual(size_t(1),output.size());
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(expectedWarning,warning);

			//delete out of bounds
			logic.start("delete 2");
			feedback = logic.getForUIFeedback();
			warning = logic.getForUIWarning();

			expectedFeedback = "Invalid line number";
			expectedWarning = EMPTY;
			expectedTaskName = "lunch meeting with cs group";
			Assert::AreEqual(expectedTaskName,output[0].getTaskName());
			Assert::AreEqual(size_t(1),output.size());
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(expectedWarning,warning);


			//reset
			logic.start("reset");
			feedback = logic.getForUIFeedback();
			output = logic.getForUIDisplay();

			expectedFeedback = RESETTED_FEEDBACK;
			Assert::AreEqual(expectedFeedback, feedback);
			Assert::AreEqual(size_t(NIL), output.size());


			//undo
			logic.start("undo");
			feedback = logic.getForUIFeedback();
			output = logic.getForUIDisplay();

			expectedFeedback = "undone reset";
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(size_t(1),output.size());

		}
		
		// reset -> add -> display -> search -> mark -> filter -> modify -> undo -> redo
		TEST_METHOD(integratedTest2) {
			Logic logic;
			string feedback;
			string expectedFeedback;
			string warning;
			string expectedWarning;
			string expectedTaskName;
			string expectedPriority;
			string expectedDeadline;
			string expectedTime;
			vector<Task> output;

			//reset
			logic.start("reset");
			

			//add 
			for(int i = 1; i <= 20; i++) {
				string data = "add " + to_string(i);
				data += "on " + to_string(i) + "/5";
				logic.start(data);
			}

			logic.start("display");
			output = logic.getForUIDisplay();

			for(int i = 0; i < 20; i++) {
				Assert::AreEqual(to_string(i+1),output[i].getTaskName());
				Assert::AreEqual(to_string(i+1) +"/5",output[i].getDeadline());
			}
		
		
			//search taskname
			logic.start("search 5");
			output = logic.getForUIDisplay();
			
			Assert::AreEqual(size_t(2),output.size());
			Assert::AreEqual(to_string(5),output[0].getTaskName());
			Assert::AreEqual(to_string(15),output[1].getTaskName());

			//search no match
			logic.start("search 25");
			output = logic.getForUIDisplay();
			feedback = "No Matches for Search";
			Assert::AreEqual(size_t(0),output.size());
		
			//search date interval
			logic.start("search 3/5 - 8/5");
			output = logic.getForUIDisplay();
		
			Assert::AreEqual(size_t(6),output.size());
			for(int i = 0; i < 6; i++) {
				Assert::AreEqual(to_string(i+3),output[i].getTaskName());
				Assert::AreEqual(to_string(i+3) +"/5",output[i].getDeadline());
			}
			
			
			//mark
			logic.start("mark 1 done");
			logic.start("mark 2 cmi");
			output = logic.getForUIDisplay();
			Assert::AreEqual(DONE,output[0].getStatus());
			Assert::AreEqual(CMI,output[1].getStatus());
			
			//mark error
			expectedFeedback = "Invalid status type. Available statuses: wip/done/cmi/archive";
			logic.start("mark 1 error");
			output = logic.getForUIDisplay();
			feedback = logic.getForUIFeedback();
			Assert::AreEqual(DONE,output[0].getStatus());
			Assert::AreEqual(expectedFeedback,feedback);

			//mark out of range
			expectedFeedback = "Invalid line number";
			logic.start("mark 0 cmi");
			feedback = logic.getForUIFeedback();
			Assert::AreEqual(expectedFeedback,feedback);



			//filter 
			logic.start("filter done");
			output = logic.getForUIDisplay();


			//currently in display is 4 cmi,5 wip,6 wip,7 wip,8 wip
			Assert::AreEqual(size_t(5),output.size());
			for(int i = 0; i < 5; i++) {
				Assert::AreNotEqual(DONE,output[i].getStatus());
			}
			for(int i = 0; i < 5; i++) {
				Assert::AreEqual(to_string(i+4),output[i].getTaskName());
			}


			//modify
			logic.start("modify 5 9999");
			feedback = logic.getForUIFeedback();
			expectedFeedback = "modified from '8' to '9999'";
			output = logic.getForUIDisplay();
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(to_string(9999),output[4].getTaskName());
			
			//undo
			logic.start("undo");
			feedback = logic.getForUIFeedback();
			expectedFeedback = "undone modify";
			output = logic.getForUIDisplay();
			Assert::AreEqual(to_string(8),output[4].getTaskName());
			Assert::AreEqual(expectedFeedback,feedback);
			
			for(int i = 0; i < 5; i ++) {
				Assert::AreEqual(to_string(i+4),output[i].getTaskName());
				Assert::AreEqual(to_string(i+4) +"/5",output[i].getDeadline());
			}


			//redo
			logic.start("redo");
			feedback = logic.getForUIFeedback();
			expectedFeedback = "redone modify";
			output = logic.getForUIDisplay();
			Assert::AreEqual(expectedFeedback,feedback);
			Assert::AreEqual(to_string(9999),output[4].getTaskName());


			//currently in display is 4 cmi,5 wip,6 wip,7 wip,9999 wip
			// modify last task to priority high, should be on top now
			logic.start("modify 5 ! h");
			logic.start("modify 5 by 4/5");
			output = logic.getForUIDisplay();
			Assert::AreEqual(to_string(9999),output[0].getTaskName());
			Assert::AreEqual(HIGH,output[0].getPriority());


			//however, now sort by task (alphabetically) so 9999, though 
			// high priority, should be at the bottom.
			logic.start("sort task");
			output = logic.getForUIDisplay();
			Assert::AreEqual(to_string(9999),output[4].getTaskName());
		}
		
	

	};
}
